package com.wanli.controller;

import cn.hutool.core.map.MapUtil;
import com.google.code.kaptcha.Producer;
import com.wanli.common.BaseController;
import com.wanli.common.Const;
import com.wanli.common.Result;
import com.wanli.domain.entity.User;
import com.wanli.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Encoder;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.Principal;
import java.time.LocalDate;
import java.util.Base64;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Slf4j
@RestController
@RequestMapping("/api")
public class IndexController extends BaseController {
    @Autowired
    private Producer producer;  // 验证码产生对象
    @Autowired
    UserService userService;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    // 上传图片转换为Base64字符串
    @PostMapping("/upload")
    public Result upload(@RequestParam("file") MultipartFile file) {
        // file参数就是前端上传图片
        try {
            // 将文件转换为 字节数组
            byte[] bytes = file.getBytes();
            // 将字节数组使用Base64编码转化为字符串
            String base64Image = "data:image/png;base64," +
                    Base64.getEncoder().encodeToString(bytes);
            return Result.success(base64Image);
        } catch (IOException e) {
            System.out.println(e.getMessage());
            return Result.fail("图片上传失败");
        }
    }

    // 显示首页登录之后用户数据
    @GetMapping("/userinfo")
    public Result userinfo(Principal principal) {
        String username = principal.getName();
        // 根据登录用户名username查询用户详细信息
        User user = userService.getUserByUsername(username);
        // 新增用户访问量：按日期
        String today = LocalDate.now().toString();
        stringRedisTemplate.opsForValue().increment(today);
        stringRedisTemplate.expire(today, 30, TimeUnit.DAYS);
        return Result.success(user);
    }

    @GetMapping("/captcha")
    public Result captcha() throws IOException {
        // 调用验证码对象 产生验证码
        String code = producer.createText();
        // 验证码需要存储 redis数据库 ( key -- value )
        // 生成一个随机key ，作为存入redis数据库的一个键
        String key = UUID.randomUUID().toString();

        // 需要将产生的验证码存储到redis数据库。登录时进行验证。
        // 存储redis中HASH类型:  key (name value)
        redisUtil.hset(Const.CAPTACHA, key, code, 60);

        // 将产生验证码变为图片
        BufferedImage image = producer.createImage(code);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ImageIO.write(image, "jpg", out);

        // 将图片转化为Base64格式：
        BASE64Encoder encoder = new BASE64Encoder();
        String str = "data:image/jpeg;base64,";
        String base64Image = str += encoder.encode(out.toByteArray());

        // 输出日志：
        log.info("验证码--{}--{}", key, code);
        return Result.success(MapUtil.builder().put("key", key).put("captchaImg", base64Image).build());
    }

    // 首先验证token，验证用户权限
    @PreAuthorize("hasAuthority('sys:user:update')")
    @PostMapping("/test")
    public Result save() {
        log.info("test权限方法访问到...");
        return Result.success("权限验证成功");
    }
}
